type tuple = [1, 2, 3];

// 我想给这个元组类型再添加一些类型，怎么做呢？

// TypeScript 类型变量不支持修改，我们可以构造一个新的元组类型：

type Push<Arr extends unknown[], Ele> = [...Arr, Ele];
{
  type res = Push<tuple, 4>;
}

// ------------------------------------

type Unshift<Arr extends unknown[], Ele> = [Ele, ...Arr];
{
  type res = Unshift<tuple, 0>;
}

// ------------------------------------

{
  type tuple1 = [1, 2];
  type tuple2 = ['a', 'b'];

  type Zip<One extends [unknown, unknown], Other extends [unknown, unknown]> = One extends [
    infer OneFirst,
    infer OneSecond,
  ]
    ? Other extends [infer TwoFirst, infer TwoSecond]
      ? [[OneFirst, TwoFirst], [OneSecond, TwoSecond]]
      : []
    : [];

  type res = Zip<tuple1, tuple2>; // type res = [[1, "a"], [2, "b"]]
}

{
  // 改造上面的元组合并 让任意个数项的元组支持合并 需要使用递归
  type tuple1 = [1, 2, 3];
  type tuple2 = ['a', 'b'];

  type Zip<One extends unknown[], Other extends unknown[]> = One extends [
    infer OneFirst,
    ...infer OneRest
  ]
    ? Other extends [infer TwoFirst, ...infer TwoRest]
      ? [[OneFirst, TwoFirst], ...Zip<OneRest, TwoRest>]
      : []
    : [];

  type res = Zip<tuple1, tuple2>; // type res = [[1, "a"], [2, "b"]]

  /**
   * 类型参数 One、Other 声明为 unknown[]，也就是元素个数任意，类型任意的数组。
   *
   * 每次提取 One 和 Other 的第一个元素 OneFirst、OtherFirst，剩余的放到 OneRest、OtherRest 里。
   *
   * 用 OneFirst、OtherFirst 构造成新的元组的一个元素，剩余元素继续递归处理 OneRest、OtherRest。
   */
}

export {};
